/*
 * Rfid
 */
package ocp.bundles.rfid.impl;

import java.util.Date;
import java.util.Hashtable;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import ocp.service.ContextProducer;
import ocp.service.ContextService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

/**
 * Clase que representa un productor de contexto. El contexto que produce 
 * representa a un medicamento con localizacion. Es un ejemplo de como será
 * la interacción del bundle RFID con OCP
 * 
 * @author Paco Lopez Marmol
 */
public class Rfid implements Runnable,ContextProducer {

    private static String locationNames[] = {
        "Farmacia.Entrada",
        "Farmacia.Ventanilla",
        "Hospital.Salida",
    };
    private static String medicamentos[] = {
        "FUZEON",
        "VIREAD",
        "SAIZEN",
        "ENBREL",
        "FLEBOGAMMA",
    };
    
    private String tagId;      
    private int location = 2;
    private int medicamento = 0;
    private Date fCad;
    private Date fEtiq;
    
    
    private boolean running = false;
    private Thread thread;
    
    private String name;    // nombre
    private ContextService cs = null;
    private ServiceRegistration sr;

    /**
     * Obtiene un identificador único 
     * @return identificador único 
     */
    private String getNewTagId() {
        return UUID.randomUUID().toString();
    }
    
    /**
     * Constructor 
     * @param name nombre del modulo
     * @param bc BundleContex 
     */
    public Rfid( String name , BundleContext bc ) {
        this.name = name;
        thread = new Thread(this);
        
        // Autoregistra el servicio de ContextProducer
        Hashtable props = new Hashtable();
        props.put("id",  name ); 
        sr = bc.registerService( ContextProducer.class.getName(), this, props );
    }

    /**
     * Obtiene el nombre del paciente
     * @return nombre del paciente
     */
    public String getName() {
        return name;
    }

    /**
     * Hilo del thread
     */
    public void run() {
        
        ContextoMedicamento contexto = null;  // contexto encapsulado
        while (running) {
            
            // si la localización es la última 
            if( location == (locationNames.length - 1) )  {
                location = 0;
                // pasa al siguiente medicamento y crea un tagId nuevo
                medicamento = (medicamento+1) % medicamentos.length;
                tagId = getNewTagId();
                // fecha de caducidad
                fCad = new Date( System.currentTimeMillis() + 1000*60*60 );
                // fecha de etiquetado
                fEtiq = new Date( System.currentTimeMillis() );
            }
            else  {
                // pasa a la siguiente localizacion
                location = (location+1) % locationNames.length;
            }
            
            // Crea un contexto de tipo Medicamento
            contexto = new ContextoMedicamento( tagId , 
                medicamentos[medicamento],locationNames[location],fCad, fEtiq );
            if( cs!=null )  {
               // Escribe el contexto en OCP
               cs.write( contexto.getContext() );
            }

            try {
                Thread.sleep(5000);
            } catch (InterruptedException ex) {             
            }
        }
    }
    
    /**
     * Activa el thread
     */
    public void start() {
       running = true; 
       this.thread.start();   
    }
    
    /**
     * Para el thread y quita el servicio ContextProducer
     */
    public void stop()  {
        running = false;
        try {
            thread.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(Rfid.class.getName()).log(Level.SEVERE, null, ex);
        }
        sr.unregister();
    }
        
    /**
     * Activa el ContextProducer. Mensaje desde ocp para indicarnos que ya
     * podemos hacer uso del servicio ContextService.
     * @param cs Interfaz del servicio ContextService
     * @see ContextService
     */
    public void activate(ContextService cs) {
        this.cs = cs;
    }

    /**
     * Desactiva el ContextProducer. Mensaje desde ocp para indicarnos que el
     * servicio ocp no esta disponible.
     */
    public void deactivate() {
        cs = null;
    }

    /**
     * Obtiene el identificador del ContextProducer. 
     * @return el identificador
     */
    public String getId() {
        return new String( name );
    }

    /**
     * Identificador para uso en log
     * @return el identificador 
     */
    private String getFullId() {
        return new String( "RFID: ");
    }
    
}
